﻿using System;
using System.Collections.Generic;
using System.Text;
using dAmn;
using llAma.Backend.Interface;
using llamaServer;

namespace llAma.Base
{
    public abstract class ChannelPropertyManagerBase : PropertyManagerBase
    {
        protected ChannelPropertyManagerBase() : base() { }
        private Dictionary<string, string> mRoomProperties = new Dictionary<string, string>();
        private Dictionary<string, long> mRoomPropertiesTimestamp = new Dictionary<string, long>();
        private Dictionary<string, string> mRoomPropertiesUsers = new Dictionary<string, string>();
        protected abstract IChannel MyChannel
        {
            get;
        }
        private void SetTimestamp(string name, long ts)
        {
            lock (mRoomPropertiesTimestamp)
            {
                name = name.ToLower().Trim();
                mRoomPropertiesTimestamp[name] = ts;
            }
        }
        private void SetTimestamp(string name)
        {
            SetTimestamp(name, GetTS(DateTime.Now));
        }
        protected void SetPropertyUser(string name, string user)
        {
            lock (mRoomPropertiesUsers)
                mRoomPropertiesUsers[name.ToLower().Trim()] = user;
        }
        protected string GetPropertyUser(string name)
        {
            string ret = string.Empty; 
            lock (mRoomPropertiesUsers)
            {
                if (mRoomPropertiesUsers.ContainsKey(name.ToLower().Trim()))
                    ret = mRoomPropertiesUsers[name.ToLower().Trim()];

            }
            return ret;
        }
        protected long GetTimestamp(string name)
        {
            long ret = 0;
            lock (mRoomPropertiesTimestamp)
            {
                name = name.ToLower().Trim();
                if (mRoomPropertiesTimestamp.ContainsKey(name))
                    ret = mRoomPropertiesTimestamp[name];
            }
            return ret;
        }
        protected void SetProperty(string name, string value)
        {
            lock (mRoomProperties)
                mRoomProperties[name.ToLower().Trim()] = value;
            SetTimestamp(name);
        }
        protected string GetProperty(string name)
        {
            string ret = string.Empty;
            lock (mRoomProperties)
            {
                if (mRoomProperties.ContainsKey(name.ToLower().Trim()))
                    ret = mRoomProperties[name.ToLower().Trim()];

            }
            return ret;
        }
        protected virtual void SendPropertiesToClient(IConnection conn)
        {
            Packet outGoing = EmptyRecvPacket;
            outGoing.cmd = "property";
            string[] properties = new string[] { "title", "topic", "motd", "botdirective" };
            for (int x = 0; x < properties.Length; x++)
            {
                string tort = GetProperty(properties[x]);
                string setby = GetPropertyUser(properties[x]);
                long ts = GetTimestamp(properties[x]);
                outGoing.args["p"] = properties[x];
                outGoing.args["by"] = setby;
                outGoing.args["ts"] = ts.ToString();
                outGoing.body = tort;
                conn.Send(outGoing.ToString());
            }
        }
        [PropertyHandler("title", PropertyHandlerMask.GETTER)]
        [PropertyHandler("topic", PropertyHandlerMask.GETTER)]
        [PropertyHandler("motd", PropertyHandlerMask.GETTER)]
        [PropertyHandler("botdirective", PropertyHandlerMask.GETTER)]
        protected void handleGetBasicProperties(Packet p, object sender, PropertyHandlerMask mask)
        {
            
            IConnection conn = (IConnection)sender;

            string tort = GetProperty(p.args["p"]);
            string setby = GetPropertyUser(p.args["p"]);
            long ts = GetTimestamp(p.args["p"]);
            Packet outGoing = EmptyRecvPacket;
            outGoing.cmd = "property";
            outGoing.args["p"] = p.args["p"].ToLower().Trim();
            outGoing.args["by"] = setby;
            outGoing.args["ts"] = ts.ToString();
            outGoing.body = tort;
            conn.Send(outGoing.ToString());
        }
        [PropertyHandler("title", PropertyHandlerMask.SETTER)]
        [PropertyHandler("topic", PropertyHandlerMask.SETTER)]
        [PropertyHandler("motd", PropertyHandlerMask.SETTER)]
        [PropertyHandler("botdirective", PropertyHandlerMask.SETTER)]
        protected void handleSetBasicProperties(Packet p, object sender, PropertyHandlerMask mask)
        {
            IConnection conn = (IConnection)sender;
            SetProperty(p.args["p"], SanitizeUserInput(p.body));
            SetPropertyUser(p.args["p"], conn.Username);
            string tort = GetProperty(p.args["p"]);
            string setby = GetPropertyUser(p.args["p"]);
            long ts = GetTimestamp(p.args["p"]);
            Packet outGoing = EmptyRecvPacket;
            outGoing.cmd = "property";
            outGoing.args["p"] = p.args["p"].ToLower().Trim();
            outGoing.args["by"] = setby;
            outGoing.args["ts"] = ts.ToString();
            outGoing.body = tort;
            MyChannel.SendToAll(outGoing.ToString());

        }
        [PacketHandler("join")]
        protected void handleJoinPacket(Packet p, IConnection conn)
        {
            SendPropertiesToClient(conn);
        }
    }
}
